package com.lkd.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lkd.dto.NodeDto;
import com.lkd.entity.*;
import com.lkd.exception.BusinessException;
import com.lkd.mapper.*;
import com.lkd.service.INodeService;
import com.lkd.vo.NodeVo;
import com.lkd.vo.PageBean;
import com.lkd.vo.RegionDetailVo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 点位表 服务实现类
 * </p>
 *
 * @author xiaotao
 * @since 2025-10-11
 */
@Service
@RequiredArgsConstructor
public class NodeServiceImpl extends ServiceImpl<NodeMapper, Node> implements INodeService {

    private final VendingMachineMapper vendingMachineMapper;
    private final RegionMapper regionMapper;
    private final NodeMapper nodeMapper;
    private final BusinessMapper businessMapper;
    private final VmTypeMapper vmTypeMapper;

    /**
     * 查看区域详情
     *
     * @param nodeDto 分页查询参数
     * @return 区域详情信息
     */
    @Override
    public PageBean<RegionDetailVo> search(NodeDto nodeDto) {
        //1.设置分页参数
        Page<Node> nodePage = new Page<>(nodeDto.getPageIndex(), nodeDto.getPageSize());

        //2.设置业务参数
        LambdaQueryWrapper<Node> wrapper = new LambdaQueryWrapper<>();

        //校验regionId是否为null值
        if (nodeDto.getRegionId() != null) {
            wrapper.eq(Node::getRegionId, nodeDto.getRegionId());
        }

        //3.执行分页查询
        Page<Node> page = this.page(nodePage, wrapper);
        List<RegionDetailVo> regionDetailVoList = page.getRecords().stream().map(node -> {
            RegionDetailVo regionDetailVo = new RegionDetailVo();
            //封装返回结果过程

            //s1:点位信息表中的属性拷贝
            BeanUtil.copyProperties(node, regionDetailVo);

            //s2:需要统计设备表中的数量------->tb_node:id
            Long vmCount = vendingMachineMapper.selectCount(new LambdaQueryWrapper<VendingMachine>().
                    eq(VendingMachine::getNodeId, node.getId()));
            regionDetailVo.setVmCount(vmCount);

            //s3:封装region对象（包含nodeCount）--->tb_node:regionId
            Region region = new Region();
            //3.1根据regionId查询出region的三个基本信息
            Region region1 = regionMapper.selectById(node.getRegionId());
            //3.2属性拷贝
            BeanUtil.copyProperties(region1, region);
            //3.3计算nodeCount
            Long nodeCount = nodeMapper.selectCount(new LambdaQueryWrapper<Node>().eq(Node::getRegionId, region.getId()));
            region.setNodeCount(nodeCount);
            regionDetailVo.setRegion(region);


            //4.Business的封装---->tb_node:business_id
            Business businessType = businessMapper.selectById(node.getBusinessId());
            regionDetailVo.setBusinessType(businessType);

            //5.封装完成，返回regionDetailVo
            return regionDetailVo;
        }).collect(Collectors.toList());

        //4.构建返回结果
        return new PageBean<>((int) page.getCurrent(), (int) page.getSize(), page.getPages(), page.getTotal(), regionDetailVoList);
    }

    /**
     * 获取点位详情
     *
     * @param nodeId
     * @return
     */
    @Override
    public List<NodeVo> queryByNodeId(Integer nodeId) {

        //首先根据nodeId查询出售货机的相关信息(售货机的一个查询构造器)
        LambdaQueryWrapper<VendingMachine> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(VendingMachine::getNodeId, nodeId);
        Long vmCount = vendingMachineMapper.selectCount(wrapper);   //统计数量是OK的
//bug:        VendingMachine vendingMachine = vendingMachineMapper.selectOne(wrapper);(可能根据nodeId会查出多条VendingMachine的数据)

        //主要原因nodeId不是主键，于是采取如下的补救措施：如果查询有多条记录，取其中第一条，这样后续的代码逻辑保持不变
        // 查询所有符合条件的记录
        List<VendingMachine> vendingMachines = vendingMachineMapper.selectList(wrapper);

        if (vendingMachines == null || vendingMachines.isEmpty()) {
            // 处理未找到的情况
            throw new BusinessException("此点位编号为" + nodeId + "下的售货机不存在！");
        }


// 取其中的若干条记录，开始封装，最后返回List<NodeVo>
        //VendingMachine vendingMachine = vendingMachines.get(0);

        //  19个属性拷贝到nodeVo中
        //根据售货机的的vm_type去查询出售货机类型表中的信息
        //------------------------------------------------->type
        //下面的这个小node的封装好复杂呀~~~
        //首先根据nodeId查询点位表的基本信息
        //nodeDetail.setBasic(nodeBasic);
        //区域id（关键,根据这个构造查询条件）
        //下面计算出nodeCount 和 nodeList的封装(这两个都是参考的regionId)
        //根据regionId展示nodeList集合(同一个regionId有哪些点位呢)
        //查询region中的基本信息，再插入nodeCount和nodeList
        //封装BusinessType
        //-------------------------------------------->小node
        //nodeVo.setRegion(region); 测试发现最外层的region为null值
        //(展示响应数据中最外层的region)
        return vendingMachines.stream().map(vendingMachine -> {

            NodeVo nodeVo = new NodeVo();
            BeanUtil.copyProperties(vendingMachine, nodeVo);//  19个属性拷贝到nodeVo中

            //根据售货机的的vm_type去查询出售货机类型表中的信息
            LambdaQueryWrapper<VmType> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(VmType::getTypeId, vendingMachine.getVmType());
            VmType type = vmTypeMapper.selectOne(wrapper1);
            nodeVo.setType(type);   //------------------------------------------------->type

            //下面的这个小node的封装好复杂呀~~~

            //首先根据nodeId查询点位表的基本信息
            NodeDetail nodeDetail = new NodeDetail();
            Node nodeBasic = getById(nodeId);
            //nodeDetail.setBasic(nodeBasic);
            BeanUtil.copyProperties(nodeBasic, nodeDetail);
            nodeDetail.setVmCount(vmCount);

            //区域id（关键,根据这个构造查询条件）
            Long regionId = nodeBasic.getRegionId();

            //下面计算出nodeCount 和 nodeList的封装(这两个都是参考的regionId)
            Long nodeCount = nodeMapper.selectCount(new LambdaQueryWrapper<Node>().eq(Node::getRegionId, regionId));

            //根据regionId展示nodeList集合(同一个regionId有哪些点位呢)
            List<Node> nodeList = nodeMapper.selectList(new LambdaQueryWrapper<Node>().eq(Node::getRegionId, regionId));

            //查询region中的基本信息，再插入nodeCount和nodeList
            Region region = regionMapper.selectById(regionId);
            region.setNodeCount(nodeCount);
            region.setNodeList(nodeList);
            nodeDetail.setRegion(region);

            //封装BusinessType
            Business businessType = businessMapper.selectById(nodeBasic.getBusinessId());
            nodeDetail.setBusinessType(businessType);
            nodeVo.setNode(nodeDetail); //-------------------------------------------->小node

            //nodeVo.setRegion(region); 测试发现最外层的region为null值

            //(展示响应数据中最外层的region)
            nodeVo.setRegion(region);

            return nodeVo;

        }).collect(Collectors.toList());
    }
}
